package heima.lm.oschina.utils;

import android.os.Environment;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.util.LruCache;

import com.jakewharton.disklrucache.DiskLruCache;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;

/**
 * Created by herenxue on 2017/3/18.
 */

public class CacheUtils {
    //把内存的1/8作为缓存
    private static final int MEMORY_CACHE_SIZE = (int) ((Runtime.getRuntime().maxMemory() / 1024) / 10);
    private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10;
    private static final String UNIQUE_NAME = UIUtils.getPackageName();
    private static final int valueCount = 1;
    private static final long CACHE_DURATION = 1000 * 60 * 3;//缓存时间
    private static CacheUtils INSTANCE;
    private static LruCache<String, String> mMemoryCache;
    private static DiskLruCache mDiskCache;


    static {
        mMemoryCache = new LruCache<String, String>(MEMORY_CACHE_SIZE) {
            @Override
            protected int sizeOf(String key, String value) {
                return value.getBytes().length;
            }
        };
        try {
            mDiskCache = DiskLruCache.open(getDiskCacheDir(UNIQUE_NAME), PackageUtlis.getVersionCode(UIUtils.getContext()), valueCount, DISK_CACHE_SIZE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private CacheUtils() {
    }

    public static void cleanCache() {
        try {
            mDiskCache.delete();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static long getCacheSize() {
        return mDiskCache.size();
    }

    public static CacheUtils getDefaultClient() {
        if (INSTANCE == null) {
            synchronized (CacheUtils.class) {
                if (INSTANCE == null)
                    INSTANCE = new CacheUtils();
            }
        }
        return INSTANCE;
    }

    //从内存中获取
    private String getMemoryCache(String key) {
        return mMemoryCache.get(key);
    }

    private void cacheToMemory(String key, String value) {
        mMemoryCache.put(key, value);
    }

    //从Disk获取
    private String getDiskCache(String key) {
        try {
            DiskLruCache.Snapshot snapshot = mDiskCache.get(key);
            if (snapshot != null) {
                DiskLruCache.Editor editor = snapshot.edit();
                if (editor != null) {
                    BufferedReader br = new BufferedReader(new InputStreamReader(editor.newInputStream(0)));
                    long cachedTime = Long.parseLong(br.readLine());
                    long currentTime = SystemClock.elapsedRealtime();
                    if (currentTime - cachedTime > CACHE_DURATION) {
                        //缓存过期
                        br.close();
                        editor.commit();
                        return null;
                    }
                    StringBuilder sb = new StringBuilder();
                    String temp;
                    while ((temp = br.readLine()) != null) {
                        sb.append(temp);
                    }
                    br.close();
                    //存储到内寸中
                    cacheToMemory(key, sb.toString());
                    editor.commit();
                    return sb.toString();
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void cacheToDisk(String key, String value) {
        try {
            DiskLruCache.Editor edit = mDiskCache.edit(key);
            if (edit != null) {
                OutputStream os = edit.newOutputStream(0);
                //第一行写入缓存时间
                BufferedWriter bw = new BufferedWriter(new PrintWriter(os));
                long cacheTime = SystemClock.elapsedRealtime();
                bw.write(String.valueOf(cacheTime));
                bw.newLine();
                bw.write(value);
                bw.flush();
                os.close();
                bw.close();
                edit.commit();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static File getDiskCacheDir(String uniqueName) {
        String cachePath;
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            cachePath = UIUtils.getContext().getExternalCacheDir().getPath();
        } else {
            cachePath = UIUtils.getContext().getCacheDir().getPath();
        }
        return new File(cachePath + File.separator + uniqueName);
    }

    public String getCache(String key) {
        String cache = getMemoryCache(key);
        if (!TextUtils.isEmpty(cache)) {
            Log.d("lm", "从内存缓存中获取");
            return cache;
        }
        cache = getDiskCache(key);
        if (!TextUtils.isEmpty(cache)) {
            Log.d("lm", "从磁盘缓存中获取");
            return cache;
        }
        return null;
    }

    public void cache(String key, String value) {
        cacheToDisk(key, value);
        cacheToMemory(key, value);
    }
}
